﻿//tyh添加
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Text;
using Estimate.Common.Entity;
using System.Text.RegularExpressions;
using Estimate.Common.DBFieldTypes;
using Estimate.Common.Repository;
using Estimate.Common.Estimate.EstimateValue;

namespace Estimate.Common.Estimate
{
    /// <summary>
    /// 根据预报的结果，获得预报的误差方向
    /// </summary>
    public class DeviationResultCulculate
    {
        /// <summary>
        /// 所有的站点
        /// </summary>
        private static Dictionary<string, AffiliationEntity> affiliations;

        /// <summary>
        /// 预报正确的站
        /// </summary>
        private List<AffiliationEntity> _correctAffiliations=new List<AffiliationEntity>();

        /// <summary>
        /// 空报站
        /// </summary>
        private List<AffiliationEntity> _emptyAffiliations=new List<AffiliationEntity>();

        /// <summary>
        /// 空报站
        /// </summary>
        private List<AffiliationEntity> _lackAffiliations=new List<AffiliationEntity>();

        /// <summary>
        /// ND站
        /// </summary>
        private List<AffiliationEntity> _NDAffiliations=new List<AffiliationEntity>();


        public DeviationResultCulculate()
        {
            //_fullInfoReport = fullInfoReport;
 
        }

        public void Clear()
        {
            ClearDeviationAffiliations();
        }

        public void ClearDeviationAffiliations()
        {
            _lackAffiliations.Clear();
            _emptyAffiliations.Clear();
            _correctAffiliations.Clear();
            _NDAffiliations.Clear();
        }

        /// <summary>
        /// 计算预报偏差
        /// </summary>
        /// <param name="connectionString">数据库连接字符串</param>
        /// <param name="deviationResult">存放计算结果的对象</param>
        /// <param name="semi"></param>
        /// <param name="semitype"></param>
        public void CulculateDeviationResultBySemiString( string connectionString,List<DeviationResult> deviationResult, string semi, ForeSemiType semitype)
        {
            if (affiliations == null)
            {
                affiliations = new Dictionary<string, AffiliationEntity>();
                AffiliationRepository affRepository = new AffiliationRepository(connectionString);
                AffiliationEntity[] entities = affRepository.GetStationLevel(4);
                foreach (AffiliationEntity entity in entities)
                    affiliations.Add(entity.code, entity);
            }

            ForeSemiType SemiType;//预报是人工站还是自动站
            string FStNum = "";// 预报站号
            PrecipitationLevelInspectionResult PrecipitationLevelInspection; // 分级降水检验
            WaterfallAmountInspectionResult WaterfallAmountInspection;  // 晴雨(雪)检验 
            WaterfallLevelInspectionResult WaterfallLevelInspection; // 一般性降水检验
            SumPrecipitationLevelInspectionResult SumPrecipitationLevelInspection;// 累加降水量检验
            string[] oserial = null;

            ClearDeviationAffiliations();

            foreach (string s in semi.Split(new char[]{'|'}))
            {
                if (s.Trim().Length < 5)
                    continue;

                oserial = s.Split(new char[] { ';' });

                if (oserial[0] == "58265" || oserial[0] == "58358")
                    continue;
                if (oserial[0] == "58248")
                    FStNum = "58252";
                else if (oserial[0] == "58154")
                    FStNum = "58151";
                else
                    FStNum = oserial[0];

                SemiType = semitype;
                PrecipitationLevelInspection = (PrecipitationLevelInspectionResult)Enum.Parse(typeof(PrecipitationLevelInspectionResult), oserial[1]);
                WaterfallAmountInspection = (WaterfallAmountInspectionResult)Enum.Parse(typeof(WaterfallAmountInspectionResult), oserial[2]);
                WaterfallLevelInspection = (WaterfallLevelInspectionResult)Enum.Parse(typeof(WaterfallLevelInspectionResult), oserial[3]);
                SumPrecipitationLevelInspection = (SumPrecipitationLevelInspectionResult)Enum.Parse(typeof(SumPrecipitationLevelInspectionResult), oserial[4]);

                if (WaterfallLevelInspection == WaterfallLevelInspectionResult.NA11 || WaterfallLevelInspection == WaterfallLevelInspectionResult.NA12)
                    _correctAffiliations.Add(affiliations[FStNum]);
                else if (WaterfallLevelInspection == WaterfallLevelInspectionResult.NB11 || WaterfallLevelInspection == WaterfallLevelInspectionResult.NB12)
                    _emptyAffiliations.Add(affiliations[FStNum]);
                else if (WaterfallLevelInspection == WaterfallLevelInspectionResult.NC11 || WaterfallLevelInspection == WaterfallLevelInspectionResult.NC12)
                    _lackAffiliations.Add(affiliations[FStNum]);
                else
                    _NDAffiliations.Add(affiliations[FStNum]);
            }

            GetResult(deviationResult);

        }

        /// <summary>
        /// 计算一组站点的平均位置 
        /// </summary>
        /// <param name="affiliations"></param>
        /// <returns></returns>
        private AffiliationEntity calculateAveragePosition(List<AffiliationEntity> affiliations)
        {
            AffiliationEntity result = new AffiliationEntity();
            result.lontitude = 0f;
            result.latitude = 0f;
            int count = 0;
            foreach (AffiliationEntity entity in affiliations)
            {
                count++;
                result.lontitude += entity.lontitude;
                result.latitude += entity.latitude;
            }
            result.lontitude /= count;
            result.latitude /= count;
            return result;
        }

        private void GetResult(List<DeviationResult> deviationResult)
        {

            if (_correctAffiliations.Count > 0 && _emptyAffiliations.Count == 0 && _lackAffiliations.Count == 0)//落区无偏差
                deviationResult.Add(new DeviationResult(DeviationKind.NoDeviation));
            else if (_correctAffiliations.Count > 0 && _emptyAffiliations.Count > 0 && _lackAffiliations.Count == 0)
            {//则落区向从正确预报站点的平均经纬度指向空报预报站点的平均经纬度的矢量方向偏差
                AffiliationEntity correct = calculateAveragePosition(this._correctAffiliations);
                AffiliationEntity empty = calculateAveragePosition(this._emptyAffiliations);
                deviationResult.Add(new DeviationResult(empty.lontitude - correct.lontitude, empty.latitude - correct.latitude, _lackAffiliations.Count, _emptyAffiliations.Count));
            }
            else if (_correctAffiliations.Count > 0 && _emptyAffiliations.Count == 0 && _lackAffiliations.Count > 0)
            {//落区向从漏报预报站点的平均经纬度指向正确预报站点的平均经纬度的矢量方向偏差
                AffiliationEntity correct = calculateAveragePosition(this._correctAffiliations);
                AffiliationEntity lack = calculateAveragePosition(this._lackAffiliations);
                deviationResult.Add(new DeviationResult(correct.lontitude - lack.lontitude, correct.latitude - lack.latitude, _lackAffiliations.Count, _emptyAffiliations.Count));
            }
            else if (_correctAffiliations.Count > 0 && _emptyAffiliations.Count > 0 && _lackAffiliations.Count > 0)
            {//以上两个矢量和方向偏差
                AffiliationEntity empty = calculateAveragePosition(this._emptyAffiliations);
                AffiliationEntity lack = calculateAveragePosition(this._lackAffiliations);
                deviationResult.Add(new DeviationResult(empty.lontitude - lack.lontitude, empty.latitude - lack.latitude, _lackAffiliations.Count, _emptyAffiliations.Count));
            }
            else if (_correctAffiliations.Count == 0 && _emptyAffiliations.Count > 0 && _lackAffiliations.Count > 0)
            {//从漏报预报站点的平均经纬度指向空报站点的平均经纬度的矢量预报反向。
                AffiliationEntity empty = calculateAveragePosition(this._emptyAffiliations);
                AffiliationEntity lack = calculateAveragePosition(this._lackAffiliations);
                deviationResult.Add( new DeviationResult(lack.lontitude - empty.lontitude, lack.latitude - empty.latitude, _lackAffiliations.Count, _emptyAffiliations.Count));
           
            }
            else if (_correctAffiliations.Count == 0 && _emptyAffiliations.Count > 0 && _lackAffiliations.Count == 0)//仅记为空报或漏报。
                 deviationResult.Add( new DeviationResult(DeviationKind.AllEmpty));
            else if (_correctAffiliations.Count == 0 && _emptyAffiliations.Count == 0 && _lackAffiliations.Count > 0)
                 deviationResult.Add( new DeviationResult(DeviationKind.AllLack));
            else
                deviationResult.Add( new DeviationResult());
           
        }


        public static DeviationResult FromString(string value)
        {
            DeviationResult result = new DeviationResult();

            string[] valueArray = value.Split(new char[] { ',' }); //Regex.Split(value, @"\,");
            result.kind = (DeviationKind)Enum.Parse(typeof(DeviationKind), valueArray[0]);
            result.X = Convert.ToSingle(valueArray[1]);
            result.Y = Convert.ToSingle(valueArray[2]);
            result.LackCount = Convert.ToInt32(valueArray[3]);
            result.EmptyCount = Convert.ToInt32(valueArray[4]);

            return result;
        }

    }
}
